(function () {
	function myCarousel(params) {
		if (!(this instanceof myCarousel)) {
			return new myCarousel(params);
		}
		var defaultConfig = {
			interval: 3000,
			// 每次轮播图时间的时间间隔，ms为单位
			duration: 600,
			// 每个动画延续的时间长度ms为单位
			arrowState: 'hover',
			// hover | always | none arrow的显示状态
			Horizontal: 'center',
			// dot的位置， 水平有 left | center | right | none
			isAutoPlay: true,
			// 是否自动播放 true | false
			currentIndex: 0,
			// 初始化索引，
			dotHandle: 'click',
			// click | mouseover dot的触发方式
			animateType: 'default',
			// default | fade | updown 动画发生的方式
			isFull: true,
			// false | true 是否全屏
			allowKb: true,
			// true | false 是否允许按键
			contain: 'container',
			// 容器的类名
			pauseType : 'mouseover',
			// mouseover | none 暂停方式，
		};
		this.config = mixin(defaultConfig, params);

		this.containerNum = null;
		// 图片的数量，抽象起来的话就是容器容纳的个数
		this.currentLength = null;
		// 具体的数量也就是containerNum-1
		this.tagContainer = null;
		// 容器节点
		this.tagMoveContainer = null;
		// 移动的大容器，也就是ul
		this.buttonParent = null;
		// 左右按钮的父级元素
		this.tagDot = null;
		// 包含全体点的容器
		this.runflag = null;
		// 定时器的标志。有些时候需要清除定时器
		this.itemIndex = -1;
		// 索引和标志
		this.imgWidth = null;
		// 参与轮播每个元素的的宽度
		this.directionFlag = 0;
		// 判断向前还是向后
		this.firstFlag = 0;
		// 第一次加载的时候不移动
		this.buttonFlag = 0;
		// 本质是判断，鼠标是否在button上面。去除这个判断会导致，鼠标从外部移入的第一次跳转跳两个页面
		this.kbflag = 0;

		this.init();
	}

	// 初始化页面的元素
	myCarousel.prototype.init = function () {
		console.log("轮播图初始化");
		// 先把this的一些属性完善
		this.tagContainer = $class('container')[0];
		this.containerNum = document.getElementsByTagName("ul")[0].getElementsByTagName("li").length;
		this.imgWidth = myCss(document.getElementsByTagName("ul")[0].getElementsByTagName("li")[0],"width");
		this.currentLength = this.containerNum - 1;
		this.tagMoveContainer = document.getElementsByTagName("ul")[0];

		//初始化button
		var btnstr = "<div class = 'button'><div class = 'left'><</div><div class = 'right'>></div></div>";
		this.tagContainer.innerHTML += btnstr;

		// 初始化顶部按钮
		var dotstr = ``;
		for (var i = 0; i != this.currentLength; i++) {
			dotstr += `<li class= "dot active" data-dotindex = "${i}"> ${i+1}</li>`;
		}
		this.tagContainer.getElementsByTagName("ol")[0].innerHTML = dotstr;

		this.render();
	};

	// 设置一些样式
	myCarousel.prototype.render = function () {
		this.tagDot = document.getElementsByTagName("ol");
		this.buttonParent = document.getElementsByClassName("button")[0];
		// 设置全屏
		if (this.config.isFull == false) {
			console.log("非全屏模式");
		} else {
			this.fullScreen();
		}

		// 设置左右按钮显示的方式
		if (this.config.arrowState === 'none') {
			addClass($class('left')[0], 'but-none');
			addClass($class('right')[0], 'but-none');
			console.log("当前是指示按钮消失的状态");
		} else if (this.config.arrowState === 'always') {
			console.log("当前是指示按钮不显示的状态");
		} else {
			addClass($class('left')[0], 'but-hover');
			addClass($class('right')[0], 'but-hover');
			console.log("当前是指示按钮覆盖显示的状态");
		}

		// 设置dot的位置
		if (this.config.Horizontal === 'center') {
			console.log("dot位置在中间");
		} else if (this.config.Horizontal === 'left') {
			myCss(this.tagContainer.getElementsByTagName("ol")[0], "left", "0");
			myCss(this.tagContainer.getElementsByTagName("ol")[0], "transform", "none");
			console.log("dot位置在左边");
		} else if (this.config.Horizontal === 'right') {
			myCss(this.tagContainer.getElementsByTagName("ol")[0], "left", "auto");
			myCss(this.tagContainer.getElementsByTagName("ol")[0], "right", "0");
			myCss(this.tagContainer.getElementsByTagName("ol")[0], "transform", "none");
			console.log("dot的位置在右边");
		} else {
			myCss(this.tagContainer.getElementsByTagName("ol")[0], "display", "none");
		}
		this.bindEvent();

		// 是否自动执行
		if (this.config.isAutoPlay) {
			this.run();
		} else {
			console.log("error");
		}
	};

	// 设置全屏的函数 render里面调用
	myCarousel.prototype.fullScreen = function () {
		var windowheight = window.innerHeight,
			windowwidth = window.innerWidth;
		// 设置container宽度和高度
		myCss($class(this.config.contain)[0], 'width', windowwidth + 'px');
		myCss($class(this.config.contain)[0], 'height', windowheight + 'px');
		// 设置ul宽度和高度
		myCss(document.getElementsByTagName("ul")[0], "width", windowwidth * this.containerNum + 'px');
		myCss(document.getElementsByTagName("ul")[0], "height", windowheight + 'px');
		for (var i = 0; i != this.containerNum; i++) {
			myCss(document.getElementsByTagName("ul")[0].getElementsByTagName("li")[i], "width", myCss($class(this.config.contain)[0], 'width'));
			myCss(document.getElementsByTagName("ul")[0].getElementsByTagName("li")[i], "height", myCss($class(this.config.contain)[0], 'height'));
		}
	};

	// 设置左右按钮事件 bindEvent里面调用
	myCarousel.prototype.btninit = function () {
		// 对前后按钮绑定点击事件
		var that = this;
		this.buttonParent.addEventListener("click", function (e) {
			var target = e.target;
			that.myClear(that.runflag);
			if (hasClass(target, "left")) {
				// 因为每次鼠标移入的时候其实itemindex已经加1了。也就是，如果我一直在按钮上面点的话，只需要减一次，如果是从外部移到按钮上面的话，需要减少两次，这里的buttonFlag就是标志位，我每次鼠标移出的时候buttonFlag就置1，移入的时候就清零
				console.log("触发左按钮点击事件");
				if (that.buttonFlag === 0) {
					that.cutItermIndex();
				} else {
					// cutItermIndex();
					that.cutItermIndex();
					that.buttonFlag = 0;
				}
			} else if (hasClass(target,"right")) {
				// 这个和向前按钮同理，如果已经加一了，就不变，否则索引加1.
				console.log("触发右按钮点击事件");
				if (that.buttonFlag === 0) {
					that.addItermIndex();
				} else {
					that.buttonFlag = 0;
				}
			} else {
				return;
			}
			if (that.itemIndex === 0) {
				if (that.directionFlag === 0) {
					that.tagMoveContainer.style.left = 0 + 'px';
					that.itemIndex = 1;
				}
			}
			if (that.itemIndex === that.currentLength) {
				if (that.directionFlag === 1) {
					console.log(that);
					console.log(that.tagMoveContainer);
					that.tagMoveContainer.style.left = - that.currentLength * parseInt(that.imgWidth) + 'px';
					that.itemIndex = that.currentLength - 1;
				}
			}
			that.moveAndAdd();

		});

	};

	// 键盘触发的事件  bindEvent里面调用
	myCarousel.prototype.keydownInit = function () {
		console.log("键盘初始化完成");
		var that = this;
		$(document).keydown(function (e) {
			if (e) {
				that.myClear(that.runflag);
				switch (e.which) {
				// 判断键盘输入的是什么，如果是左方向键或者右方向键，那么就执行对应的上下函数，然后退出，其余所有键都退出
				//也就是说鼠标要点击到左右切换按钮(a标签)才能够使用左右按键控制切换,点击轮播图，input控件，文本区域都不行 
				case 37:
					console.log("按键左被触发");
					// this.prev();
					that.kbflag = 1;
					that.cutItermIndex();
					console.log(that.itemIndex + "123");
					break;
				case 39:
					console.log("按键右被触发");
					// this.next();
					that.kbflag = 0;
					that.addItermIndex();
					break;
				default:
					return;
				}
				if (that.itemIndex === 0) {
					if (that.kbflag === 0) {
						that.tagMoveContainer.style.left = 0 + 'px';
						that.itemIndex = 1;
					}
				}
				if (that.itemIndex === 0) {
					if (that.kbflag === 1) {
						console.log(2);
						that.tagMoveContainer.style.left = - that.currentLength * parseInt(that.imgWidth) + 'px';
						that.itemIndex = that.currentLength - 1;
					} 
				} else {
					console.log(3);
				}
				// that.moveAndAdd();
				e.preventDefault();
			}
			that.cutItermIndex();
			that.run();
		});
	};

	// 绑定事件 render的最后，初始化完页面信息之后调用
	myCarousel.prototype.bindEvent = function () {
		// 设置键盘
		if (this.config.allowKb) {
			console.log("当前模式允许键盘操控");
			this.keydownInit();
		} else {
			console.log("当前模式不允许键盘");
		}

		// 绑定左右按钮事件
		if (this.config.arrowState !== "none") {
			this.btninit();
			console.log("给左右按钮绑定函数完成");
		} else {
			console.log("按钮函数取消");
		}

		// 绑定dot事件
		if (this.config.Horizontal !== 'none') {
			var that = this;
			this.tagContainer.getElementsByTagName("ol")[0].addEventListener(this.config.dotHandle, function (e) {
				var target = e.target;
				that.myClear(that.runflag);
				if (target.tagName === 'LI') {
					if (that.itemIndex === parseInt(target.dataset.dotindex)) {
						return;
						// 最后向前跳的时候，如果是第一页，那么不应该变化，并且吧位置归0
					} else if (that.itemIndex === that.currentLength) {
						if (that.itemIndex - parseInt(target.dataset.dotindex) === that.currentLength) {
							that.tagMoveContainer.style.left = 0 + 'px';
							that.itemIndex = 1;
							// 如果是第二页，那么就让他从第一页开始
						} else if (parseInt(target.dataset.dotindex) === 1) {
							that.tagMoveContainer.style.left = 0 + 'px';
							that.itemIndex = 1;
							that.moveAndAdd();
						} else {
							that.itemIndex = parseInt(target.dataset.dotindex);
							that.moveAndAdd();
						}
	
					} else {
						that.itemIndex = parseInt(target.dataset.dotindex);
						that.moveAndAdd();
					}
				} else {
					return ;
				}
			});
			console.log("给每个dot绑定事件");
		} else {
			console.log("dot不存在");
		}

		// 绑定鼠标移入事件
		if (this.config.pauseType === 'mouseover') {
			console.log("鼠标暂停");
			this.tagContainer.addEventListener("mouseenter", function () {
				that.buttonFlag = 0;
				that.myClear(that.runflag);
			});
			this.tagContainer.addEventListener("mouseleave", function () {
				that.buttonFlag = 1;
				that.run();
			});
			var up = document.getElementsByClassName("left")[0];
			up.addEventListener("mouseenter", function () {
				that.directionFlag = 1;
			});
			up.addEventListener("mouseleave", function () {
				that.directionFlag = 0;
			});
		} else {
			console.log("鼠标滑入不暂停");
		}

		console.log("carousel的一些默认配置");
		console.log(this);
	};

	// 封装一下
	function runCarousel(msg) {
		return myCarousel(msg);
	}

	myCarousel.prototype.run = function() {
		this.addItermIndex();
		this.moveAndAdd();
		if (this.itemIndex === 0) {
			this.tagMoveContainer.style.left = 0 + 'px';
			if (this.directionFlag === 0 && this.firstFlag === 1) {
				this.itemIndex = 1;
				this.moveAndAdd();
			}
			this.firstFlag = 1;
		}
		var that = this;
		this.runflag = setTimeout(() => {
			this.run();
		}, this.config.interval);
	};

	// 清空所有的active类
	myCarousel.prototype.mapRemove = function(sameEl, className) {
		var tagEl = $class(sameEl);
		for (var i = 0, j = tagEl.length; i != j; i++) {
			deleteClass(tagEl[i], className);
		}
	};

	// 删除所有的active，并给当前的加
	myCarousel.prototype.setActive = function() {
		this.mapRemove("dot", "active");
		var index = this.itemIndex;
		// index等于5说明是第六张，这个时候要等同于给第一张设置active
		if (index === this.currentLength) {
			index = 0;
		}
		var tag = document.getElementsByClassName("dot")[index];
		addClass(tag, "active");
	};

	// 索引加一
	myCarousel.prototype.addItermIndex = function() {
		this.itemIndex ++;
		if (this.itemIndex > this.currentLength) {
			this.itemIndex = 0;
		}
	};

	// 索引减一
	myCarousel.prototype.cutItermIndex = function() {
		this.itemIndex --;
		if (this.itemIndex < 0) {
			console.log(this.itemIndex +"     213123     " + this.currentLength);
			this.itemIndex = this.currentLength;
		}
	};

	// 求出目标距离并跳转加活跃类
	myCarousel.prototype.moveAndAdd = function() {
		var tagpos = -(this.itemIndex) * parseInt(this.imgWidth);
		this.setActive();
		this.moveTou(tagpos);
	};

	// 清除函数
	myCarousel.prototype.myClear = function(flag) {
		if (flag) {
			clearTimeout(flag);
		}
	};

	// 运动函数
	myCarousel.prototype.moveTou = function (endPos) {
		var element = this.tagMoveContainer;
		// console.log(element);
		this.myClear(element.move);
		var startPos = parseInt(myCss(element, "left"));
		// console.log(startPos);
		if (startPos === endPos) {
			return true;
		}
		if (startPos < endPos) {
			startPos += 5;
		}
		if (startPos > endPos) {
			startPos -= 5;
		}
		element.style.left = startPos + 'px';
		this.tagMoveContainer = document.getElementsByTagName("ul")[0];
		var that = this;
		element.move = setTimeout(function () {
			that.moveTou(endPos);
		}, 1);
	};




	// 假装是从接口得到数据
	function getDate(url) {
		$.ajax({
			type: "GET",
			url: url,
			data: "",
			dataType: "json",
			success: function (res) {
				// 从json读取数据，并把图片初始化
				var container = $class('container')[0];
				var ultarget = $class("container")[0].getElementsByTagName("ul")[0];
				var data = res.imgArray;
				var length = res.imgArray.length + 1;
				var str = ``;
				for (var i = 0; i != res.imgArray.length; i++) {
					// li标签里面填写任何东西都无所谓。 重要的是li标签
					str += `<li data-index = ${i}><img src="${data[i].picUrl}" alt="${data[i].picAlt}"></li>`;
				}
				str += `<li data-index = ${0}><img src="${data[0].picUrl}" alt="${data[0].picAlt}"></li>`;
				myCss(ultarget, "width", length * parseInt(myCss(container, "width")) + "px");
				ultarget.innerHTML = str;


				runCarousel({
					isFull: false,
					contain: 'container',
					arrowState: 'hover',
					allowKb: true,
					Horizontal: 'center',
					// mouseover 可能会存在问题，写到的时候要注意
					dotHandle: 'click',
				});
			},
			error: function (res) {
				console.log(res);
			}
		});
	}

	getDate("../json/data.json");
})();